<template>

  <div class="star-data">

    <div class="option">
      <div class="option-container adaption">

        <div class="bookmark-name">

          <template v-if="!editing">
            <div class="bookmark-name-container">
              {{name}}
            </div>
            <span @click="rename('bookmarkName')" class="iconfont icon-editor"></span>
          </template>

          <input v-else @blur="stopEdit" v-on:keyup.enter="stopEdit" class="rename" v-model="name" type="text" id="bookmarkName">

        </div>

        <div class="bookmark-option-container">

          <g-button class="btn del" @click="removeBookmark">删除收藏夹</g-button>

          <div class="bookmark-range" v-show="!isEmpty">

            <span @click="changeSortTime">
              <i class="iconfont" :class="`icon-sort-${currentBookmark.timeOrder}`"></i> 时间
            </span>

            <span @click="changeRangeType">
              <template v-if="isListView"><i class="iconfont icon-tiling"></i> 平铺</template>
              <template v-else><i class="iconfont icon-menu"></i> 列表</template>
            </span>
          </div>

          <div class="search" v-show="!isEmpty">
            <input type="text" class="input-search" v-model="currentBookmark.search" v-on:keyup.enter="query" placeholder="搜索">
            <div class="btn-search" @click="query">
              <i class="iconfont icon-loading icon-spin" v-show="isLoading"></i>
              <i class="iconfont icon-search" v-show="!isLoading"></i>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="data-list-container">

      <div v-if="isEmpty" class="no-data">
        <img src="../../../static/img/no-data.png">
        <div class="no-data-tip">该收藏夹尚未收藏数据</div>
      </div>

      <template>
        <div class="wrapper-body">
          <div v-show="isListView" class="list-view-header" :class="[ isListView ? 'adaption-list' : 'adaption']">
            <div class="name">数据名称</div>
            <div class="data-count">数据量</div>
            <div class="date">上传日期</div>
            <div class="data-option">操作</div>
          </div>
          <g-scrollbar class="data-vertical-scroll" :class="{'with-header': isListView}">
            <div :class="[ isListView ? 'adaption-list' : 'adaption']">

              <div class="datas-content">
                <ul class="data-view">
                  <component v-for="(data,index) in currentBookmark.items" :dataType="dataType" :currentMenu="currentMenu" :is="currentBookmark.view" type="star" :data="data" :index="index" :key="data.uid" :isPrivate="data.dataType === 'private'" v-on:open="open" v-on:data-preview="preview" v-on:move-out-store="moveOutStore" v-on:set-current-menu="setCurrentMenu"></component>
                </ul>

                <div class="add-more-wrapper">
                  <button class="add-more" v-show="currentBookmark.hasNext" @click="addMore()" :disabled="isLoading">
                    <span v-show="!isLoading">
                      <i class="iconfont icon-flip-down"></i> 加载更多
                    </span>
                    <span v-show="isLoading">
                      <i class="iconfont icon-loading spin"></i> 加载中…
                    </span>
                  </button>
                </div>
              </div>
            </div>
          </g-scrollbar>
        </div>
      </template>

    </div>

    <transition-group name="fade">

      <div :key="'public-data-preview'">
        <data-preview :is-private="previewData.dataType === 'private'" dataType="data" :base-path="basePath" :preview-data="previewData" v-on:close-preview="closePreview" v-if="openPreview && previewData"></data-preview>
      </div>

    </transition-group>

  </div>

</template>

<script>
import Bus from "@/utils/event_bus";
import TilingWrapper from "./tiling-wrapper";
import ListWrapper from "./list-wrapper";
import DataPreview from "components/preview/data-preview";
import GScrollbar from "components/common/g-scrollbar";
import GButton from "components/common/g-button";
import {
  bookmark as bookmarkAPI,
  data as dataAPI,
  publicData as publicAPI
} from "@/api";

const viewTypes = ["map", "table", "metadata"];
const limit = 60;

export default {
  name: "star-data",

  components: {
    ListWrapper,
    TilingWrapper,
    DataPreview,
    GScrollbar,
    GButton
  },

  data() {
    const dataType = "data";
    return {
      dataType,
      isLoading: false, // 加载数据列表时的搜索组件是否显示缓冲环
      previewData: "", // 当前预览数据信息
      openPreview: false, // 是否打开预览窗口
      currentMenu: "", // 用于控制dataWrapper中打开的菜单

      role: this.$root.geohey.user.role || "", // 用户角色

      stores: {},
      currentBookmark: {},
      bookmarkUid: "",
      name: "",
      editing: false,
      hasNext: false
    };
  },

  props: {
    bookmarks: Array
  },

  beforeRouteEnter(to, from, next) {
    let bookmarkUid = to.params.bookmarkUid;
    next(vm => {
      vm.bookmarkUid = bookmarkUid;
      vm.initData();
    });
  },

  beforeRouteUpdate(to, from, next) {
    let bookmarkUid = to.params.bookmarkUid;

    if (bookmarkUid === "bookmark") {
      return;
    }

    this.bookmarkUid = bookmarkUid;
    this.initData();
    next();
  },

  beforeRouteLeave(to, from, next) {
    this.closePreview();
    // this.$destroy();
    next();
  },

  mounted() {
    Bus.$on("clear-bookmark-data", this.clearBookmarkData);

    let uid = this.$route.params.bookmarkUid;

    this.bookmarks.forEach(item => {
      if (item.key === uid) {
        Bus.$emit("on-submenu-change", item.name);
      }
    });
  },

  created() {
    // 检查URL中是否已经包含打开特定数据和视图的参数
    let params = this.$route.params;

    if (Object.keys(params).length > 0 && params.uid && params.view) {
      this.openDataView(params.uid, params.view);
    }
  },

  activated() {
    this.$emit("on-view-load");
  },

  computed: {
    isEmpty() {
      return !(this.currentBookmark.items && this.currentBookmark.items.length);
    },

    basePath() {
      return `/data/bookmark/${this.bookmarkUid}`;
    },

    isListView() {
      return !!(this.currentBookmark.view === "list-wrapper");
    },

    bookmarkName() {
      let a = undefined;

      this.bookmarks.forEach(n => {
        if (n.key === this.bookmarkUid) {
          a = n.name;
        }
      });

      return a;
    }
  },

  directives: {
    focus: {
      componentUpdated: function(el, { value }) {
        if (value) {
          el.focus();
        }
      }
    }
  },

  watch: {
    bookmarkName() {
      this.name = this.bookmarkName;
    }
  },

  methods: {
    open() {},

    rename(id) {
      this.editing = true;

      this.$nextTick(function() {
        document.getElementById(id).focus();
      });
    },

    async stopEdit() {
      if (!this.editing || this.name === this.bookmarkName) {
        return;
      }

      let result = await bookmarkAPI.update(this.bookmarkUid, {
        name: this.name
      });

      if (!result || result.data.code != 0) {
        this.$message.error(result.data.msg || "重命名失败");
        this.name = this.bookmarkName;
        return;
      }

      this.$message.success("重命名成功");
      this.$emit("rename", this.bookmarkUid, this.name);
    },

    removeBookmark() {
      let success = false;
      let promise = this.$confirm(
        `删除收藏夹后不可恢复，确定删除？`,
        "删除收藏夹",
        {
          type: "warning",
          confirmButtonType: "danger",
          confirmButtonText: "确定",
          beforeClose: async (action, instance, done) => {
            if (action === "confirm") {
              instance.confirmButtonLoading = true;
              instance.confirmButtonText = "删除中...";
              instance.cancelButtonDisabled = true;

              let result = await bookmarkAPI.remove(this.bookmarkUid);

              if (!result || result.data.code != 0) {
                done();
                this.$message.error("删除收藏夹失败");
                return;
              }

              success = true;
              done();
              this.$message.success("删除收藏夹成功");
              instance.confirmButtonLoading = false;
            } else {
              done();
            }
          }
        }
      );

      promise
        .then(() => {
          if (!success) return;

          this.$emit("remove-bookmark", this.bookmarkUid);
          delete this.stores[this.bookmarkUid];
          this.$router.push({ path: "/data/private-data" });
        })
        .catch(() => {});
    },

    moveOutStore(data) {
      let uid = data.uid;
      let success = false;

      let promise = this.$confirm(`将数据移出收藏夹？`, "移除", {
        type: "warning",
        confirmButtonType: "danger",
        confirmButtonText: "确定",
        // parent: this.$refs.myData,
        beforeClose: async (action, instance, done) => {
          if (action === "confirm") {
            instance.confirmButtonLoading = true;
            instance.confirmButtonText = "操作中...";
            instance.cancelButtonDisabled = true;

            let result = await bookmarkAPI.removeData(this.bookmarkUid, uid);

            if (!result || result.data.code != 0) {
              done();
              this.$message.error("操作失败");
              return;
            }
            done();
            success = true;
            this.$emit("move-out-store", uid);
            instance.confirmButtonLoading = false;
          } else {
            done();
          }
        }
      });

      promise
        .then(() => {
          if (!success) return;

          let dataList = this.stores[this.bookmarkUid]["items"];

          dataList.forEach((n, index) => {
            if (n.uid === uid) {
              this.$message.success("移除数据成功");
              dataList.splice(index, 1);
            }
          });
        })
        .catch(() => {
          // this.$message.error('取消')
        });
    },

    async changeSortTime() {
      if (this.loading) return;

      this.currentBookmark.timeOrder =
        this.currentBookmark.timeOrder === "desc" ? "asc" : "desc";

      this.currentBookmark.page = 1;

      let result = await this.getData();

      if (result.code != 0) {
        this.$message.error("查询失败");
        return;
      }

      let data = result.data;

      this.currentBookmark.items = data;
    },

    changeRangeType() {
      if (this.loading || this.isEmpty) return;
      this.currentBookmark.view =
        this.currentBookmark.view === "list-wrapper"
          ? "tiling-wrapper"
          : "list-wrapper";
    },

    async initData() {
      let bookmarkUid = this.bookmarkUid;
      let bookmarkItem = this.stores[bookmarkUid];

      if (bookmarkItem && bookmarkItem.items.length) {
        this.currentBookmark = bookmarkItem;
        return;
      }

      let result = await this.getData();

      if (result.code != 0) {
        this.$message.error("获取数据失败");
        return;
      }

      bookmarkItem = {
        items: result.data,
        page: 1,
        view: "tiling-wrapper",
        search: "",
        hasNext: false,
        timeOrder: "desc"
      };

      this.stores[bookmarkUid] = this.currentBookmark = bookmarkItem;

      //关闭加载界面
      this.$emit("change-loading", {
        add: !!bookmarkItem.items.length,
        key: this.$data.bookmarkUid
      });
    },

    async getData() {
      this.isLoading = true;
      let bookmarkUid = this.bookmarkUid;
      let bookmarkItem = this.stores[bookmarkUid];

      let page = bookmarkItem ? bookmarkItem.page : 1;
      let search = bookmarkItem ? bookmarkItem.search : "";
      let timeOrder = bookmarkItem ? bookmarkItem.timeOrder : "desc";

      let params = {
        limit,
        page,
        search,
        timeOrder
      };

      let result = await bookmarkAPI.dataList(bookmarkUid, params);

      this.isLoading = false;
      return result.data;
    },

    async addMore() {
      let page = this.currentBookmark.page;
      page = page + 1;

      let result = await this.getData();

      if (result.code != 0) {
        this.$message.error("加载数据失败");
        page = page - 1;
        return;
      }

      let data = result.data;
      let items = this.currentBookmark.items;

      this.currentBookmark.items = items.concat(data);
    },

    async query() {
      this.currentBookmark.page = 1;

      let result = await this.getData();
      // console.log(result);
      // this.currentBookmark.items=[];
      if (result.code != 0) {
        this.$message.error("查询失败");
        return;
      }

      let data = result.data;

      if (data.length === 0) {
        this.$message.warning("未找到相应内容");

        return;
      }

      this.currentBookmark.items = data;
    },

    setCurrentMenu(menu) {
      this.currentMenu = menu;
    },

    preview(data) {
      this.previewData = data;
      this.openPreview = true;
    },

    closePreview() {
      this.previewData = "";
      this.openPreview = false;
    },

    async openDataView(uid, viewType) {
      // 获取数据详情
      let dataInfo = await this.getDataInfo(uid);

      if (!dataInfo) {
        return;
      }

      if (viewTypes.indexOf(viewType) === -1) {
        viewType = "map";
      }

      let customPreviewData = {
        uid: uid,
        geometryType: dataInfo.geomType,
        extent: dataInfo.extent,
        name: dataInfo.name,
        count: dataInfo.count,
        view: viewType,
        convertEnd: !!dataInfo.geomType,
        isPrivate: false
      };

      // 打开预览窗口
      this.openPreview = true;
      this.previewData = customPreviewData;
    },

    /**
     * 获取数据详情
     * @param string uid 数据UID
     */
    async getDataInfo(uid) {
      let currentBookmark = this.currentBookmark;
      let type = "";

      currentBookmark.forEach(n => {
        if (n.uid == uid) {
          type = n.dataType;
        }
      });

      let dataInfo = "";

      if (type === "private") {
        dataInfo = await dataAPI.info(uid);
      } else {
        dataInfo = await publicAPI.info(uid);
      }

      if (dataInfo.data.code === 0) {
        return dataInfo.data.data;
      }

      this.$message.error("您请求的数据不存在");

      return null;
    },

    upload() {
      this.openUpload = true;
    },

    clearBookmarkData(uids) {
      uids.forEach(n => {
        let store = this.stores[n];
        if (store) {
          delete this.stores[n];
        }
      });
    }
  }
};
</script>

<style lang="scss" rel="stylesheet/scss" scoped>
@import "common";

@media screen and (max-width: 1200px) {
  .search {
    display: none !important;
  }

  .bookmark-name {
    padding-right: 230px !important;
  }
}

@media screen and (max-width: 900px) {
  .search {
    display: none !important;
  }

  .bookmark-range {
    display: none !important;
  }

  .bookmark-name {
    padding-right: 100px !important;
  }
}

.star-data {
  height: 100%;
  width: 100%;
  font-size: 12px;
  position: relative;
  @include box-sizing(border-box);

  // .list-table-wrapper{

  //     @media screen and (max-width: 1050px) {
  //         min-width: 720px;
  //         -ms-overflow-style: -ms-autohiding-scrollbar;
  //         -webkit-overflow-scrolling: touch;
  //     }
  // }

  .option {
    width: 100%;
    position: absolute;
    top: 0;
    padding: 18px 0;
    @include box-shadow(0 4px 6px 2px rgba(255, 255, 255, 0.3));

    .option-container {
      overflow: hidden;
      position: relative;

      .bookmark-name {
        width: 100%;
        height: 32px;
        padding-right: 500px;
        line-height: 32px;
        position: relative;

        .bookmark-name-container {
          float: left;
          height: 100%;
          line-height: 32px;
          font-size: 16px;
          color: $dark;
          @include text-overflow();
          max-width: calc(100% - 30px);
          overflow: hidden;
          padding-right: 28px;
        }

        > span {
          color: $gray;
          float: left;
          margin-left: 6px;
          position: relative;
          cursor: pointer;
          left: -24px;

          &:hover {
            color: $info;
          }
        }

        > .rename {
          height: 100%;
          width: 100%;
          max-width: 150px;
          font-size: 16px;
          color: $deepGray;
          border-bottom: 1px solid $bdGray;
        }
      }

      .bookmark-option-container {
        position: absolute;
        top: 0;
        right: 0;

        > .btn {
          float: right;
          width: 90px;
        }

        > .btn.del:hover {
          color: $danger !important;
          border-color: $danger !important;
        }

        > .bookmark-range {
          display: block;
          float: right;
          color: $gray;
          padding: 6px 34px;
          cursor: pointer;
          text-align: right;
          @include user-select(none);
          > span {
            line-heigth: 32px;
            height: 32px;
            text-align: center;
            font-size: 14px;
            padding: 0 5px;

            &:hover {
              color: $primary;
            }
          }
        }

        > .search {
          float: right;
          width: 210px;
          color: $gray;
          position: relative;

          .input-search {
            width: 210px;
            height: 32px;
            padding: 6px 42px 6px 12px;
            border: 1px solid $bdGray;
            border-radius: 16px;

            &:focus {
              border-color: $info;
            }
          }

          .btn-search {
            width: 32px;
            height: 32px;
            text-align: center;
            line-height: 32px;
            cursor: pointer;
            position: absolute;
            right: 6px;
            top: 0;

            > i {
              font-size: 14px;
            }

            &:hover {
              color: $primary;
            }
          }
        }
      }
    }
  }
}

.spread-enter-active {
  @include animation(spread-in 0.3s);
}
.spread-leave-active {
  @include animation(spread-out 0.3s);
}

@include keyframes(spread-in) {
  0% {
    height: 0px;
  }
  100% {
    height: 196px;
  }
}

@include keyframes(spread-out) {
  0% {
    height: 196px;
  }
  100% {
    height: 0px;
  }
}

.spin {
  display: inline-block;
  font-size: 12px;
  @include animation(icon-spin 2s infinite linear);
}

@include keyframes(icon-spin) {
  from {
    @include rotate(0);
  }
  to {
    @include rotate(359);
  }
}
</style>
